package com.game;

import android.graphics.Path;
import android.graphics.PointF;
import android.graphics.RectF;
import android.util.Log;

public class PuzzleUtil {
	private final String TAG = PuzzleUtil.class.getSimpleName();
	
	public static final int EDGE_CONCAVE = -1; // ��
	public static final int EDGE_FLAT = 0; // ƽ
	public static final int EDGE_CONVEX = 1; // ͹
	//public static final int EDGE_COUNT = 3;		//modify by chenchq
	
	
	public static final int EDGE_LEFT = 10;
	public static final int EDGE_TOP = 11;
	public static final int EDGE_RIGHT = 12;
	public static final int EDGE_BOTTOM = 13;
	
	private Path path;
	private float left, top, right, bottom;
	private int leftState = 0, topState = 0, rightState = 0, bottomState = 0;
	private float radius;
	private float angle = 270;
	
	private int index = 0;
	
	public PuzzleUtil() {
		path = new Path();
	}
	
	public PuzzleUtil copyUtil() {
		PuzzleUtil util = new PuzzleUtil();
		util.setEdgeState(leftState, topState, rightState, bottomState);
		return util;
	}
	
	public PuzzleUtil(float left, float top, float right, float bottom, float radius) {
		this.left = left;
		this.top = top;
		this.right = right;
		this.bottom = bottom;
		this.radius = radius;
		path = new Path();
		initPath();
	}
	
	public void setRadius(float radius) {
		this.radius = radius;
	}
	
	public void setEdge(float left, float top, float right, float bottom) {
		this.left = left;
		this.top = top;
		this.right = right;
		this.bottom = bottom;
		
		this.radius = (right - left) / 6;
		
		initPath();
	}
	
	public void setEdgeState(int leftState, int topState, int rightState, int bottomState) {
		this.leftState = leftState;
		this.topState = topState;
		this.rightState = rightState;
		this.bottomState = bottomState;
	}
	
	public void setIndex(int index) {
		this.index = index;
	}
	
	public int getIndex() {
		return index;
	}
	
	public int getTopState() {
		return this.topState;
	}
	
	public int getBottomState() {
		return this.bottomState;
	}
	
	public int getLeftState() {
		return this.leftState;
	}
	
	public int getRightState() {
		return rightState;
	}
	
	public void setOffset(float offsetX, float offsetY) {
		left += offsetX;
		right += offsetX;
		
		top += offsetY;
		bottom += offsetY;
		
		initPath();
	}
	
	public float getLeft() {
		return left;
	}
	
	public float getTop() {
		return top;
	}
	
	public float getRight() {
		return right;
	}
	
	public float getBottom() {
		return bottom;
	}
	
	public Path getPath() {
		return path;
	}
	
	public void initPath() {
		Log.v(TAG, "Util left " + left + " top " + top);
		path.reset();
		path.moveTo(left, top);
		if (topState == EDGE_FLAT) {
			path.lineTo(right, top);
		} else if (topState == EDGE_CONCAVE) {
			Tuqi tq = new Tuqi();
			tq.setNodes(left, top, right, bottom, EDGE_TOP);
			path.lineTo(tq.node1.x, tq.node1.y);
			path.arcTo(new RectF((float) ((left + right)/2 - radius), (float) (top - (1 - Math.sqrt(2)/2)*radius), (float) ((left + right)/2 + radius), (float) (top + (1 + Math.sqrt(2)/2)*radius)), 225f, -angle, false);
			path.lineTo(right, top);
		} else if (topState == EDGE_CONVEX) {
			Tuqi tq = new Tuqi();
			tq.setNodes(left, top, right, bottom, EDGE_TOP);
			path.lineTo(tq.node1.x, tq.node1.y);
			path.arcTo(new RectF((float) ((left + right)/2 - radius), (float) (top - (1 + Math.sqrt(2)/2)*radius), (float) ((left + right)/2 + radius), (float) (top + (1 - Math.sqrt(2)/2)*radius)), 135f, angle, false);
			path.lineTo(right, top);
		}
		if (rightState == EDGE_FLAT) {
			path.lineTo(right, bottom);
		} else if (rightState == EDGE_CONCAVE) {
			Tuqi tq = new Tuqi();
			tq.setNodes(left, top, right, bottom, EDGE_RIGHT);
			path.lineTo(tq.node1.x, tq.node1.y);
			path.arcTo(new RectF((float) (right - (1 + Math.sqrt(2)/2)*radius), (float) ((top + bottom)/2 - radius), (float) (right + (1 - Math.sqrt(2)/2)*radius), (float) ((top + bottom)/2 + radius)), 315f, -angle, false);
			path.lineTo(right, bottom);
		} else if (rightState == EDGE_CONVEX) {
			Tuqi tq = new Tuqi();
			tq.setNodes(left, top, right, bottom, EDGE_RIGHT);
			path.lineTo(tq.node1.x, tq.node1.y);
			path.arcTo(new RectF((float) (right - (1 - Math.sqrt(2)/2)*radius), (float) ((top + bottom)/2 - radius), (float) (right + (1 + Math.sqrt(2)/2)*radius), (float) ((top + bottom)/2 + radius)), 225f, angle, false);
			path.lineTo(right, bottom);
		}
		if (bottomState == EDGE_FLAT) {
			path.lineTo(left, bottom);
		} else if (bottomState == EDGE_CONCAVE) {
			Tuqi tq = new Tuqi();
			tq.setNodes(left, top, right, bottom, EDGE_BOTTOM);
			path.lineTo(tq.node2.x, tq.node2.y);
			path.arcTo(new RectF((float) ((left + right)/2 - radius), (float) (bottom - (1 + Math.sqrt(2)/2)*radius), (float) ((left + right)/2 + radius), (float) (bottom + (1 - Math.sqrt(2)/2)*radius)), 45f, -angle, false);
			path.lineTo(left, bottom);
		} else if (bottomState == EDGE_CONVEX) {
			Tuqi tq = new Tuqi();
			tq.setNodes(left, top, right, bottom, EDGE_BOTTOM);
			path.lineTo(tq.node2.x, tq.node2.y);
			path.arcTo(new RectF((float) ((left + right)/2 - radius), (float) (bottom - (1 - Math.sqrt(2)/2)*radius), (float) ((left + right)/2 + radius), (float) (bottom + (1 + Math.sqrt(2)/2)*radius)), 315f, angle, false);
			path.lineTo(left, bottom);
		}
		if (leftState == EDGE_FLAT) {
			path.lineTo(left, top);
		} else if (leftState == EDGE_CONCAVE) {
			Tuqi tq = new Tuqi();
			tq.setNodes(left, top, right, bottom, EDGE_LEFT);
			path.lineTo(tq.node2.x, tq.node2.y);
			path.arcTo(new RectF((float) (left - (1 - Math.sqrt(2)/2)*radius), (float) ((top + bottom)/2 - radius), (float) (left + (1 + Math.sqrt(2)/2)*radius), (float) ((top + bottom)/2 + radius)), 135f, -angle, false);
			path.lineTo(left, top);
		} else if (leftState == EDGE_CONVEX) {
			Tuqi tq = new Tuqi();
			tq.setNodes(left, top, right, bottom, EDGE_LEFT);
			path.lineTo(tq.node2.x, tq.node2.y);
			path.arcTo(new RectF((float) (left - (1 + Math.sqrt(2)/2)*radius), (float) ((top + bottom)/2 - radius), (float) (left + (1 - Math.sqrt(2)/2)*radius), (float) ((top + bottom)/2 + radius)), 45f, angle, false);
			path.lineTo(left, top);
		}
		path.close();
	}
	
	class Tuqi {
		PointF node1, node2;
		
		public void setNodes(float left, float top, float right, float bottom, int whichEdge) {
			switch (whichEdge) {
			case EDGE_LEFT:
				node1 = new PointF(left, (float) ((top + bottom)/2 - (Math.sqrt(2)/2)*radius));
				node2 = new PointF(left, (float) ((top + bottom)/2 + (Math.sqrt(2)/2)*radius));
				break;
			case EDGE_TOP:
				node1 = new PointF((float) ((left + right)/2 - (Math.sqrt(2)/2)*radius), top);
				node2 = new PointF((float) ((left + right)/2 + (Math.sqrt(2)/2)*radius), top);
				break;
			case EDGE_RIGHT:
				node1 = new PointF(right, (float) ((top + bottom)/2 - (Math.sqrt(2)/2)*radius));
				node2 = new PointF(right, (float) ((top + bottom)/2 + (Math.sqrt(2)/2)*radius));
				break;
			case EDGE_BOTTOM:
				node1 = new PointF((float) ((left + right)/2 - (Math.sqrt(2)/2)*radius), bottom);
				node2 = new PointF((float) ((left + right)/2 + (Math.sqrt(2)/2)*radius), bottom);
				break;
			}
		}
	}
}
